/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fvm;

import algebra.HMean;
import algebra.Point2d;
import gui.shapes.Shape_FVE;
import java.util.ArrayList;

/**
 *
 * @author max
 */
public class FVElement {

    private Point2d supp_point; //Stützstelle
    private double dx,dy; //Durchmesser FVE in x und y Richtung
    private FVPermeability perm; //hydraulische Durchlässigkeit
    
    
    
    private boolean boundary = false;
    private boolean noflow = false;
    private boolean flow = false;
    
    
    private ArrayList<Double> h;
    private FVElement   north = null,
                        south = null,
                        west= null,
                        east = null;
    private int i,j;
    private Shape_FVE shape;
    private ArrayList<Double> qx = null, qy = null;
    private double S_0 = 0;//1e-4;
    private double ne = 1;
     
    
    
      public FVElement(Point2d supp_point, double dx, double dy){

          
          this.h = new ArrayList<>();

          this.qx = new ArrayList<>();
          this.qy = new ArrayList<>();
    this.supp_point = supp_point;
    this.h.add(0.);
    this.qx.add(0.);
    this.qy.add(0.);

    this.perm = new FVPermeability();
    this.dy = dy;
    this.dx = dx;
    
    }
      

      
      public void setnoflow(boolean bool){
          
          
          h.set(0, -1d);
          noflow = bool;
          flow = !bool;
          
          boundary = bool;
      
      
      }
      
      
      
      public void sethkand1(double hn){this.h.set(this.h.size()-1, hn);}
      
      
      public boolean isflow(){return flow;}
      
      public boolean isnoflow(){return noflow;}
      
      public void setflow(boolean bool){
      
      noflow = !bool;
      flow = bool;
     
      boundary=bool;
     
    
      }
      
      public void setne(double ne){this.ne = ne;}
      public double getne(){return ne;}
      
      
      public void addshape(Shape_FVE shape){this.shape = shape;}
      
      
      
            public FVElement(Point2d supp_point, int i, int j, double dx, double dy){

                this.h = new ArrayList<>();
                this.qx = new ArrayList<>();
                this.qy = new ArrayList<>();
    this.supp_point = supp_point;
    this.h.add(0.);
    qx.add(0.);
    qy.add(0.);
    this.perm = new FVPermeability();
    this.i = i;
    this.j = j;
    this.dy = dy;
    this.dx = dx;
    
    }
            
            public void setneighb(FVElement north, FVElement south, FVElement west, FVElement east){
            
            this.north = north;
            this.east = east;
            this.west = west;
            this.south = south;
            }
            
            public FVElement getNorthNeigh(){return north;}
            public FVElement getSouthNeigh(){return south;}
            public FVElement getWestNeigh(){return west;}
            public FVElement getEastNeigh(){return east;}

            public void setNorthNeigh(FVElement north){this.north = north;}
            public void setSouthNeigh(FVElement south){this.south = south;}
            public void setWestNeigh(FVElement west){this.west = west;}
            public void setEastNeigh(FVElement east){this.east = east;}
            
            public void seti(int i){this.i=i;}
            public void setj(int j){this.j=j;}
            
            public int geti(){return i;}
            public int getj(){return j;}
            
            public FVPermeability getperm(){return perm;}
            
            public double getdx(){return dx;}
            public double getdy(){return dy;}
            
      
      public Point2d getsupppoint(){return supp_point;}
      
      public ArrayList<FVElement> getallNeighb(){
      
      ArrayList<FVElement> temp = new ArrayList<>();
      if(north!=null) temp.add(north);
      if(east!=null) temp.add(east);
      if(south!=null) temp.add(south);
      if(west!=null) temp.add(west);
      
      return temp;
      
      }
     
      
      
      public void addh(double h){
          this.h.add(h);
      }
      
      public double gethk(){
          return this.h.get(this.h.size()-1);}
      
      public void seth0(double h){
      
      this.h = new ArrayList<>();
      this.h.add(h);
      
      }
      
      public double getS0(){return S_0;}
      public void setS0(double so){S_0=so;}
      
      public void setboundary(boolean bool,double h){
      
          //dirichlet
          
      this.boundary = bool;
      flow = !bool;
      
      noflow = !bool;
      this.h = new ArrayList<>();
      this.h.add(h);
      }
      public double geth(int i){
      
          return this.h.get(i);
      
      }
      
      public void deltehs(){
      
          double h0 = h.get(0);
          this.h = new ArrayList<>();
          h.add(h0);
      }
      
      public boolean setq(int i, double qx, double qy){
      
      if(i>this.qx.size()) return false;
      else {if(i==this.qx.size()){
      
          this.qx.add(qx);
          this.qy.add(qy);
      return true;
      }
      else{
      
      
      this.qx.set(i, qx);
      this.qy.set(i, qy);
      return true;
      }
      
      }
      }
      
      public double getqx(int i){
      
      if(i>=qx.size()) return 0.;
      else return qx.get(i);
      
      }
      
      public double getqy(int i){
      
      if(i>=qy.size()) return 0.;
      else return qy.get(i);
      
      }
      
      public boolean isboundary(){return boundary;}
   
      
      
      public double gethNW(){
      
          
      if(north!=null&&south!=null&&west!=null&&east!=null&&gethk()>0){
      if(north.isnoflow() || west.isnoflow() || north.getWestNeigh().isnoflow()){return -1d;}
          double n = north.gethk();
          double w = west.gethk();
          double nw = north.getWestNeigh().gethk();
          
          
      
      return (n+w+nw+this.gethk())/4;
      }
      else return -1;
      
      }
      
      public double gethNE(){
       
      if(north!=null&&south!=null&&west!=null&&east!=null&&gethk()>0){
        if(north.isnoflow() || east.isnoflow() || north.getEastNeigh().isnoflow()){return -1d;}
          double n = north.gethk();
          double e = east.gethk();
          double noe = north.getEastNeigh().gethk();
          
          
      
      return (n+e+noe+this.gethk())/4;
      }
      else return -1;
      
      }
      
      public double gethSW(){
       
      if(north!=null&&south!=null&&west!=null&&east!=null&&gethk()>0){
        if(south.isnoflow() || west.isnoflow() || south.getWestNeigh().isnoflow()){return -1d;}
          double s = south.gethk();
          double w = west.gethk();
          double sw = south.getWestNeigh().gethk();
          
          
      
      return (s+w+sw+this.gethk())/4;
      }
      else return -1;
      
      }
      
      public double gethSE(){
      
         
          
      
     
      if(north!=null&&south!=null&&west!=null&&east!=null&&gethk()>0){
           
             if(south.isnoflow() || east.isnoflow() || south.getEastNeigh().isnoflow()){return -1d;}
          double s,e,se;
          
         
       s = south.gethk();
          
         
          e = east.gethk();
          
         
        se = south.getEastNeigh().gethk();
          
          
          return (s+e+se+this.gethk())/4;
      }
       else return -1;
      
      }
      

      public boolean isdirichlet(){
      
          return (isboundary() && !isnoflow() && !isflow());
      
      }
      
}
